﻿/* Copyright (c) 2003-2008 GD GameDuell GmbH, All Rights Reserved
 * This document is strictly confidential and sole property of GD GameDuell GmbH, Berlin, Germany
 */

package de.gameduell.framework.geom {
	import flash.display.DisplayObjectContainer;
	import flash.display.Sprite;
	import flash.geom.Point;		

	/**
	 * @author Gevorg Sargsyan
	 */
	public class QuadraticBezier {
		/** the start point of the curve */
		private var _startPoint : Point;
		/** the control point of the curve */
		private var _controlPoint : Point;
		/** the control point of the curve */
		private var _endPoint : Point;
		private var _drawClip : Sprite;

		
		/**
		 * constructor of the class
		 * 
		 * @param startPoint the first point wich defines the curve
		 * @param controlPoint the control point of the curve
		 * @param endPoint the endpoint of the curve
		 */
		public function QuadraticBezier(startPoint : Point,controlPoint : Point,endPoint : Point) {
			_startPoint = startPoint;
			_controlPoint = controlPoint;
			_endPoint = endPoint;
		}

		
		/**
		 * returns a position on the curve in dependance of the given time
		 * 
		 * examples:
		 * 1. getPosition(0) 	would return the startPoint
		 * 2. getPosition(1) 	would return the endPoint
		 * 3. getPosition(0.5)	would return a point on the curve between the startpoint and the endpoint
		 * 
		 * @param time a value between 0 and 1
		 * @return a point on the curve (dependance of the given time)
		 */
		public function getPosition(time : Number) : Point {		
			var sc1 : Number = (1 - time) * (1 - time);
			var sc2 : Number = 2 * time * (1 - time);
			var sc3 : Number = time * time;
			
//			var tmp0 : Point = _startPoint.multiply(sc1);//			var tmp1 : Point = _controlPoint.multiply(sc2);
//			var tmp2 : Point = _endPoint.multiply(sc3);
			var tmp0 : Point = multiply(_startPoint, sc1);
			var tmp1 : Point = multiply(_controlPoint, sc2);
			var tmp2 : Point = multiply(_endPoint,sc3);			
			
			//return tmp0.addPoint(tmp1.addPoint(tmp2));			return tmp0.add(tmp1.add(tmp2));
		}
		
		private function multiply(pointA : Point, aFactor : Number) : Point {
			return new Point(pointA.x * aFactor, pointA.y * aFactor);
		}

		
		/**
		 * returns the startPoint of the curve
		 * 
		 * @return the startPoint of the curve
		 */
		public function get startPoint() : Point {
			return _startPoint;
		}

		
		/**
		 * returns the controlPoint of the curve
		 * 
		 * @return the controlPoint of the curve
		 */
		public function get controlPoint() : Point {
			return _controlPoint;
		}

		
		/**
		 * returns the endPoint of the curve
		 * 
		 * @return the endPoint of the curve
		 */
		public function get endPoint() : Point {
			return _endPoint;
		}

		
		/**
		 * sets the startPoint of the curve
		 * 
		 * @param start the startPoint of the curve
		 */
		public function set startPoint(start : Point) : void {
			_startPoint = start;
		}

		
		/**
		 * sets the controlPoint of the curve
		 * 
		 * @param start the controlPoint of the curve
		 */
		public function set controlPoint(control : Point) : void {
			_controlPoint = control;
		}

		
		/**
		 * sets the endPoint of the curve
		 * 
		 * @param start the endPoint of the curve
		 */
		public function set endPoint(end : Point) : void {
			_endPoint = end;
		}

		
		/**
		 * draws the curve
		 * 
		 * @param the MovieClip to draw to
		 */
		public function draw( container : DisplayObjectContainer ) : void {
			if(_drawClip == null) {
				_drawClip = new Sprite(); 
				container.addChild(_drawClip);
			} else {
				clear();
			}
			_drawClip.graphics.lineStyle(1, 0x000000, 100);
			_drawClip.graphics.moveTo(_startPoint.x, _startPoint.y);
			_drawClip.graphics.curveTo(_controlPoint.x, _controlPoint.y, _endPoint.x, _endPoint.y);
		}

		
		public function clear() : void {
			_drawClip.graphics.clear();
		}
	}
}
